#include <sys/dir.h>
#include <iostream>
#include <errno.h>
#include <string.h>
#include <vector>
#include "../../catalog/audio/AudioCatalog.h"
#include <extractor.h>


typedef std::vector<std::string> VectorString;
//#include <inotifytools/inotify.h>

#define synchronized(x) \
({\
   pthread_mutex_init(&(x.getMutex()),NULL);\
   pthread_mutex_trylock(&(x.getMutex()));\
})

#define end_synchronized(x) \
({\
    pthread_mutex_unlock(&(x.getMutex()));\
    pthread_mutex_destroy(&(x.getMutex()));\
})


#include "LinuxFileInfo.h"
//#include "../../manager/"
using namespace std;

class Object {
    public :

        pthread_mutex_t& getMutex(){
            return this->mutex;
        }

    private :
        pthread_mutex_t mutex;
};
class Chota : public Object{
public:

    explicit Chota(int a) {
        this->value = a;
    }
private:
    int value;
};

std::string trim(std::string string) {
    while (string[0] == ' ')
        string = string.substr(1, string.length() - 1);
    while (string[string.length() - 1] == ' ')
        string = string.substr(0, string.length() - 1);
    return string;
}

bool findQuote(std::string & path, VectorString& vectorPath) {
    int index = 0;
    int find = 0;
    if (path[0] == '\"') {
        path.erase(0, 1);
        find = path.find_first_of("\"", index);
        if (find == -1) {
            return true;
        }
        vectorPath.push_back(path.substr(index, find));
        path = path.substr(find + 1, path.length() - (find + 1));
        path = trim(path);
    }
}

VectorString split(std::string& string, std::string& separator) {
    VectorString path;
    std::string element;
    int index = 0;
    int find = 0;
    while ((unsigned int) find < string.length() && find != -1) {
        //findQuote(string, path);
        if (string.length() > 0) {
            find = string.find_first_of(separator, index);
            if (find == -1) {
                element = string.substr(0, string.length());
                path.push_back(element);
                break;
            }
            element = string.substr(0, find);
            element = trim(element);

            string = string.substr(find + 1, string.length() - (find + 1));
            if (string != " ")
                string = trim(string);
            path.push_back(element);
            find = 0;
        }
    }
    return path;
}





typedef bool (*file_match_function) (const string&, const string&);

//void findMatch(ArchivoPalabras& arch , const string& pattern, const string& path, file_match_function match) {
//    DIR* d = opendir(path.c_str());
//    static struct dirent* dirp;
//    vector<string> dirs;
//    if (!d) {
//        cerr << "Unable to open directory " << path << endl;
//        cerr << "Error is " << strerror(errno) << "(" << errno << ")" << endl;
//        return;
//    }
//    while ((dirp = readdir(d)) != NULL) {
//        if (0 == strcmp(".", dirp->d_name) ||
//                0 == strcmp("..", dirp->d_name)) continue; // skip . and ..
//        string candidate(path + "/" + dirp->d_name);
//        try {
//            if (LinuxFileInfo::isRegularFile(candidate)) {
//                if (LinuxFileInfo::canRead(candidate) && match(pattern, candidate)) {
//                    std::string archName(dirp->d_name);
//                    //arch.agregarPalabra(archName);
//                }
//            } else if (LinuxFileInfo::isDirectory(candidate)) {
//                dirs.push_back(candidate);
//            }
//        } catch (const invalid_argument& ia) {
//            cerr << "Caught exception on path " << candidate << ":  " << ia.what() << endl;
//        }
//    }
//    closedir(d);
//    for (vector<string>::const_iterator ci = dirs.begin(); ci != dirs.end(); ++ci) {
//        findMatch(arch,pattern, *ci, match);
//    }
//}

bool matchSaraza(const string& dato, const string& dato2) {
    //cout << "El Match es" << dato << "yyy" << dato2 << endl;
    return true;
}

int maingdsgds(int argc, char * argv[]) {
    Chota chota(5);
    VectorString terminos;
    AudioCatalog catalog(std::string("catalogo_mp3"));
    //ArchivoPalabras archPalabras(std::string("archivoPalabras.dat"));
//    findMatch(archPalabras,"*.txt", "/home/ariel", matchSaraza);
    //findMatch(archPalabras,"*.txt", "/home/ariel", matchSaraza);
//    synchronized(chota);
//    end_synchronized(chota);
      //std::cout << "Las Cantidad de palabras son::" << archPalabras.obtenerCantidadPalabras()<<std::endl;


    EXTRACTOR_ExtractorList * plugins;
    EXTRACTOR_KeywordList * md_list;
    EXTRACTOR_KeywordList * key=NULL;
    //plugins = EXTRACTOR_loadDefaultLibraries();
    plugins = EXTRACTOR_loadDefaultLibraries();
    plugins = EXTRACTOR_loadConfigLibraries(plugins,"libextractor_pdf");//:libextractor_mp3:libextractor_ogg:libextractor_mpeg");//:libextractor_ogg:libextracor:libextractor_mpeg");
    //plugins = EXTRACTOR_addLibrary(plugins,"libextractor_mp3");
    md_list = EXTRACTOR_getKeywords(plugins, "/home/ariel/Desktop/gilada.cpp");
    if(md_list != NULL){
        if(strcmp(EXTRACTOR_extractLast(EXTRACTOR_MIMETYPE,md_list),"application/pdf") == 0){
            for(key=md_list;key != NULL; key=(key->next)){
                std::string termino(key->keyword);
                std::string separador(" ");
                VectorString aux = split(termino,separador);
                terminos.insert(terminos.end(),aux.begin(),aux.end());
            }
        }
        key = NULL;
        catalog.agregarDocumento(std::string("/home/ariel/Desktop/") , terminos);
    }
    EXTRACTOR_freeKeywords(md_list);
    EXTRACTOR_removeAll(plugins);
    catalog.mostrarTerminosDoc();
    /* unload plugins */
    //removeList(md_list);
    //    removePlugins(plugins);
    //    std::cout << "saraza" <<std::endl;
    //    std::string string;
    //    EXTRACTOR_ExtractorList * plugins;
    //    EXTRACTOR_KeywordList * md_list;
    //    plugins = EXTRACTOR_loadDefaultLibraries();
    //
    //    md_list = EXTRACTOR_getKeywords(plugins, "/home/ariel/Desktop/tp_1_2009.pdf");
    //
    //    string += EXTRACTOR_extractLast(EXTRACTOR_MIMETYPE,md_list);
    ////    while(md_list!=NULL) {
    ////       if(EXTRACTOR_isBinaryType(md_list->keywordType)){
    ////           std::cout << "El Archivo es Binario" << std::endl;
    ////       }
    ////       md_list = md_list->next;
    ////    }
    ////    EXTRACTOR_printKeywords(stdout, md_list);
    ////    std::cout << "MIME TYPE IS "<<string<< std::endl;
    //    //EXTRACTOR_getKeywords2()
    //    EXTRACTOR_freeKeywords(md_list);
    //    EXTRACTOR_removeAll(plugins);
    //    /* unload plugins */
    //    //findMatch("*.txt", "/Users", matchSaraza);
    return 0;
}




//int mainito(void)
//{
//    string watch_dir = "/home/ariel/Desktop";
//
//    try {
//        Inotify notify;
//
//        InotifyWatch watch(watch_dir, IN_MODIFY | IN_CREATE | IN_DELETE);
//        notify.Add(watch);
//
//        cout << "Watching directory " << watch_dir << endl << endl;
//        for (;;) {
//            notify.WaitForEvents();
//
//            size_t count = notify.GetEventCount();
//            while (count > 0) {
//                InotifyEvent event;
//                bool got_event = notify.GetEvent(&event);
//
//                if (got_event) {
//                    string mask_str;
//                    event.DumpTypes(mask_str);
//
//                    string filename = event.GetName();
//
//                    cout << "[watch " << watch_dir << "] ";
//                    cout << "event mask: \"" << mask_str << "\", ";
//                    cout << "filename: \"" << filename << "\"" << endl;
//                }
//
//                count--;
//            }
//        }
//    } catch (InotifyException &e) {
//        cerr << "Inotify exception occured: " << e.GetMessage() << endl;
//    } catch (exception &e) {
//        cerr << "STL exception occured: " << e.what() << endl;
//    } catch (...) {
//        cerr << "unknown exception occured" << endl;
//    }
//
//    return 0;
//}
